﻿using System;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using MediaController.Subs;
using MediaController.Subs.Provider;

namespace SubsDownloader
{
    public partial class Main : Form
    {
        readonly object _syncObject = new object();
        private Thread _searchThred;
        private readonly SubtitlesProvider _subtitlesProvider;
        private string _path;

        public Main()
        {
            InitializeComponent();
            _subtitlesProvider = new SratimProvider();
            _subtitlesProvider.SmartSearch = true;
            _subtitlesProvider.FileFounded += SubtitlesProviderFileFounded;
            _subtitlesProvider.ProgressChanged += SubtitlesProviderProgressChanged;
            _subtitlesProvider.NoTitleMachFound += SubtitlesProviderNoTitleMachFound;
            _subtitlesProvider.NoSubtitleMachFound += SubtitlesProviderNoSubtitleMachFound;
        }

        private void CheckBoxFilterCheckedChanged(object sender, EventArgs e)
        {
            mediaFileBindingSource.Filter = _checkBoxFilter.Checked ? "HasSubs = 0" : "";
        }

        private void ButtonSerachClick(object sender, EventArgs e)
        {
            var button = (Button)sender;

            if (button.Text == "Search")
            {
                if (string.IsNullOrEmpty(_textBoxSearchPath.Text) || !Directory.Exists(_textBoxSearchPath.Text)) return;
                _subtitlesData.Clear();                
                _path = _textBoxSearchPath.Text;
                _subtitlesProvider.ThreadCount = Convert.ToInt32(_numericUpDownThread.Value);

                _textBoxSearchPath.Enabled = false;
                button.Text = "Stop";
                _searchThred = new Thread(Search);
                _searchThred.Start();
            }
            else
            {
                EnableControls();
                _searchThred.Abort();
                _searchThred.Join();
            }
        }

        private void Search()
        {
            try
            {
                _subtitlesProvider.DownloadSubtitle(_path, SearchOption.AllDirectories);
                EnableControls();
            }
            catch (Exception ex)
            {
                string logPath = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "Logs");
                if (!Directory.Exists(logPath))
                    Directory.CreateDirectory(logPath);
                string fileName = Path.Combine(logPath, string.Format("{0}_{1}.txt", DateTime.Now.ToString("yyyyMMdd"), Guid.NewGuid()));
                File.WriteAllText(fileName, ex.ToString());
            }
        }

        private void EnableControls()
        {
            if (InvokeRequired)
            {
                Invoke(new Action(EnableControls));
            }
            else
            {
                _buttonSerach.Text = "Search";
                _buttonSerach.Enabled = true;
                _textBoxSearchPath.Enabled = true;
            }
        }

        void SubtitlesProviderFileFounded(SubsProgressEventArgs obj)
        {
            AddFile(obj.TitleFileInfo);
        }

        private void AddFile(TitleFileInfo titleFileInfo)
        {
            if (InvokeRequired)
            {
                Invoke(new Action<TitleFileInfo>(AddFile), titleFileInfo);
            }
            else
            {
                var mediaFileRow = _subtitlesData.MediaFile.NewMediaFileRow();
                TitleFileInfo titleFile = checkBoxSearchByFolder.Checked
                                              ? titleFileInfo.TitleFileInfoByFolderName
                                              : titleFileInfo;
                mediaFileRow.CD = titleFile.CD;
                mediaFileRow.Episode = titleFile.Episode;
                mediaFileRow.FileName = titleFileInfo.FilePath;
                mediaFileRow.HasSubs = titleFile.HasSubs;
                mediaFileRow.IsSeries = titleFile.IsSeries;
                mediaFileRow.IsTwoCD = titleFile.IsTwoCD;
                mediaFileRow.Season = titleFile.Season;
                mediaFileRow.TitleName = titleFile.TitleName;
                mediaFileRow.Year = titleFile.Year;
                _subtitlesData.MediaFile.AddMediaFileRow(mediaFileRow);
            }
        }

        void SubtitlesProviderProgressChanged(SubsProgressEventArgs obj)
        {
            lock (_syncObject)
            {
                if (obj.TitleFileInfo == null) return;

                var mediaFileRow = _subtitlesData.MediaFile.FindByFileName(obj.TitleFileInfo.FilePath);
                var logRow = _subtitlesData.SubLog.NewSubLogRow();
                logRow.Time = DateTime.Now;
                logRow.Message = obj.UserState.ToString();
                logRow.MediaFileRow = mediaFileRow;
                logRow.SetParentRow(logRow);
                _subtitlesData.SubLog.AddSubLogRow(logRow);
                if (obj.UserState.ToString().Contains("Subtitles successfully downloaded"))
                {
                    mediaFileRow.HasSubs = true;
                    foreach (var childRow in mediaFileRow.GetChildRows(_subtitlesData.MediaFile.ChildRelations[1]))
                    {
                        childRow.Delete();
                    }
                }
            }
        }

        void SubtitlesProviderNoTitleMachFound(object arg1, NoMatchTitleFoundEventArgs arg2)
        {
            lock (_syncObject)
            {
                if (arg2.MediaFileInfo == null) return;

                var mediaFileRow = _subtitlesData.MediaFile.FindByFileName(arg2.MediaFileInfo.FilePath);
                mediaFileRow.WatingForSelection = true;
                foreach (var movieResult in arg2.MovieResults)
                {
                    var selectionRow = _subtitlesData.Selection.NewSelectionRow();
                    selectionRow.Text = string.Format("{0} - {1}", movieResult.Name, movieResult.Year);
                    selectionRow.Value = new TitleSelection(arg2.MediaFileInfo, movieResult);
                    selectionRow.SetParentRow(mediaFileRow);
                    _subtitlesData.Selection.AddSelectionRow(selectionRow);
                }
            }
        }

        void SubtitlesProviderNoSubtitleMachFound(object arg1, NoMatchSubtitleFoundEventArgs arg2)
        {
            lock (_syncObject)
            {
                if (arg2.MediaFileInfo == null) return;

                var mediaFileRow = _subtitlesData.MediaFile.FindByFileName(arg2.MediaFileInfo.FilePath);
                foreach (var childRow in mediaFileRow.GetChildRows(_subtitlesData.MediaFile.ChildRelations[1]))
                {
                    childRow.Delete();
                }
                foreach (var subtitleResult in arg2.SubtitleResults)
                {
                    var selectionRow = _subtitlesData.Selection.NewSelectionRow();
                    selectionRow.Text = string.Format("{0} - {1}", subtitleResult.Name, subtitleResult.CDCount);
                    selectionRow.Value = new SubtitelsSelection(arg2.MediaFileInfo, subtitleResult);
                    selectionRow.SetParentRow(mediaFileRow);
                    _subtitlesData.Selection.AddSelectionRow(selectionRow);
                }
            }
        }

        private void ListBoxSelectionSelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void ListBoxSelectionDoubleClick(object sender, EventArgs e)
        {
            if (_listBoxSelection.SelectedValue is SubtitelsSelection)
            {
                var selection = (SubtitelsSelection)_listBoxSelection.SelectedValue;
                _subtitlesProvider.DownloadSubtitle(selection.Subtitle.Link, selection.Title);
            }
            else if (_listBoxSelection.SelectedValue is TitleSelection)
            {
                var selection = (TitleSelection)_listBoxSelection.SelectedValue;

                _subtitlesProvider.FindSubtitles(selection.Title, selection.TitleResult);
            }
            _dataGridViewTitles.Focus();
        }

        private void CheckBoxSearchByFolderCheckedChanged(object sender, EventArgs e)
        {
            _subtitlesProvider.SearchByFolderName = checkBoxSearchByFolder.Checked;
        }
    }
}
